import { v4 as uuidv4 } from "uuid";
import { ElMessage } from "element-plus";
import axios from "axios";
import { LowCodeImp, EventCenterImp } from './type'
import { Selector } from "./selector";
const lowCodeInstance = Symbol("lowCodeInstance");

export class EventCenter implements EventCenterImp {
    private [lowCodeInstance]: LowCodeImp;
    private events!: {
        [propName: string]: Function
    };
    constructor(lowcode: LowCodeImp,) {
        this[lowCodeInstance] = <LowCodeImp>lowcode
        this[lowCodeInstance] && this.init()
    }

    init() {

        if (this[lowCodeInstance].eventCollection && this[lowCodeInstance].eventCollection.length > 0) {
            this[lowCodeInstance].eventCollection.map(item => {
                try {
                    this.on(item.code, new Function(`controller`, `${item.func}`))
                } catch (error) {
                    console.log('自定义事件出现错误', error)
                }
            })
        }

    }

    addEvent(type: string, describe: string, options: any = {}, event: string) {
        let map = {
            code: uuidv4(),
            type: type,
            options: options,
            describe: describe,
            func: event
        }
        this[lowCodeInstance].eventCollection.push(map)
        this.init()
    }

    editorEvent(type: string, code: string, options: any = {}, describe: string, event: string) {
        let eventMap = this[lowCodeInstance].eventCollection.find(item => item.code == code)
        if (eventMap) {
            eventMap['func'] = event
            eventMap['type'] = type
            eventMap['options'] = options
            eventMap['describe'] = describe
        }
        this.init()
    }

    removeEvent(code: string) {
        let index = this[lowCodeInstance].eventCollection.findIndex(item => item.code == code)
        this[lowCodeInstance].eventCollection.splice(index, 1)
    }

    //添加监听
    on(key: string, listener: Function): EventCenterImp {
        //this.events存储所有的处理函数
        if (!this.events) {
            this.events = {}
        }
        this.events[key] = listener
        return this as EventCenterImp
    }

    //触发一个事件，也就是通知
    fire(key: string): Promise<any> | boolean {
        if (!this.events || !this.events[key]) return false
        var args = Array.prototype.slice.call(arguments, 1) || []

        if (!this[lowCodeInstance]) {
            this.events[key].apply(this, args)
            return false
        }
        return new Promise((resolve, reject) => {
            try {
                let parameter = [
                    {
                        data: this[lowCodeInstance].model,
                        $: (name: string) => {
                            let component = new Selector(this[lowCodeInstance])
                            component.find.call(component, name)
                            return component
                        },
                        axios: axios,
                        ElMessage: ElMessage,
                    }
                ]
                let result = this.events[key].apply(this, parameter)
                if (result) {
                    resolve(result)
                } else {
                    resolve(true)
                }
            } catch (error) {
                reject(error)
            }

        })

    }

    //取消监听
    off(key: string, listener: string) {
        if (!key && !listener) {
            this.events = {}
        }
        if (key && !listener) {
            delete this.events[key]
        }
    }

}